Passed
Push — master ( 0543ef...cf6673 )
by Miloš
02:59
created

FirebaseStorage.getUserRef   A

Complexity

Conditions 2

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 11
rs 9.95
c 0
b 0
f 0
cc 2
1
import { Injectable } from '@angular/core';
2
import { AngularFireAuth } from '@angular/fire/auth';
3
import { AngularFirestore, AngularFirestoreDocument, } from '@angular/fire/firestore';
4
import * as firebase from 'firebase';
5
import { Observable, of } from 'rxjs';
6
import { switchMap } from 'rxjs/operators';
7
import { FirebaseUserModel, UserModel } from '..';
8
import { IStorageConcreteProviderOptions } from './i-storage-concrete-provider-options';
9
import { IStorageProvider } from './i-storage-provider';
10
import { IStorageProviderOptions } from './i-storage-provider-options';
11
12
@Injectable({
13
    providedIn: 'root',
14
})
15
export class FirebaseStorage<User extends UserModel = UserModel>
16
    implements IStorageProvider<User> {
17
18
    options: IStorageConcreteProviderOptions = {
19
        userTable: 'users',
20
    }
21
22
    public constructor(
23
        protected angularFireAuth: AngularFireAuth,
24
        protected angularFirestore: AngularFirestore,
25
    ) {
26
    }
27
28
    public async updateStoredDataByUser(user: User): Promise<void> {
29
        if (user.uid) {
30
            const userRef = this.getUserRef(user.uid);
31
32
            const data = new FirebaseUserModel({
33
                displayName: user.displayName,
34
                email: user.email,
35
                photoURL: user.photoURL,
36
                uid: user.uid,
37
            });
38
39
            return userRef.set(Object.assign({}, data), {merge: true});
40
        } else {
41
            return;
42
        }
43
    }
44
45
    public getUserRef(
46
        userUid: string,
47
    ): AngularFirestoreDocument<FirebaseUserModel> {
48
        if (this.options.userTable === null) {
49
            throw new Error('userTable is not specified!');
50
        }
51
52
        return this.angularFirestore
53
            .collection(this.options.userTable)
54
            .doc(userUid);
55
    }
56
57
    public updateStoredDataByFirebaseUser(firebaseUser: firebase.User): Promise<void> {
58
        if (firebaseUser.uid) {
59
            const userRef = this.getUserRef(firebaseUser.uid);
60
61
            const data = new FirebaseUserModel({
62
                displayName: firebaseUser.displayName,
63
                email: firebaseUser.email,
64
                photoURL: firebaseUser.photoURL,
65
                uid: firebaseUser.uid,
66
            });
67
68
            return userRef.set(Object.assign({}, data), {
69
                merge: true,
70
            });
71
        } else {
72
            throw new Error('Firebase user has no UID.');
73
        }
74
    }
75
76
    public fetchUser(): Promise<User | unknown | null> {
77
        return this.subscribeUser().toPromise();
78
    }
79
80
    public subscribeUser(): Observable<User | unknown | null> {
81
        // Get the auth state, then fetch the Firestore user document or return null
82
        return this.angularFireAuth.authState.pipe(
83
            switchMap((user: any) => {
84
                if (user) {
85
                    // User is logged in
86
                    return this.angularFirestore
87
                        .doc<FirebaseUserModel>(
88
                            `${this.options.userTable}/${user.uid}`,
89
                        )
90
                        .valueChanges()
91
                        .pipe(
92
                            switchMap((userFirebase: any) => {
93
                                return new Observable(subscriber => {
94
                                    subscriber.next(
95
                                        Object.assign<User, any>(
96
                                            this.getNewUser(),
97
                                            userFirebase,
98
                                        ),
99
                                    );
100
                                    subscriber.complete();
101
                                });
102
                            }),
103
                        );
104
                }
105
                // Logged out
106
                return of(null);
107
            }),
108
        );
109
    }
110
111
    /**
112
     * Override this method if you want to use custom model class
113
     */
114
    protected getNewUser(): User {
115
        return new UserModel() as User;
116
    }
117
}
118